package com.pet.framework.wechat;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.pet.common.core.domain.entity.SysUser;
import com.pet.common.core.redis.RedisCache;
import com.pet.common.utils.DateUtils;
import com.pet.system.domain.*;
import com.pet.system.mapper.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class WechatService {

    @Value("${wechat.AppId}")
    private String appId;

    @Value("${wechat.AppSecret}")
    private String appSecret;

    @Value("${wechat.LoginUrl}")
    private String loginUrl;

    @Value("${wechat.TokenUrl}")
    private String tokenUrl;

    @Value("${wechat.PhoneNumUrl}")
    private String phoneNumUrl;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private PetCustomerMapper customerMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysDictDataMapper dictDataMapper;

    @Autowired
    private PetProductMapper petProductMapper;

    @Autowired
    private PetApplyMapper applyMapper;

    @Autowired
    private PetCustomerUserMapper petCustomerUserMapper;

    @Autowired
    private PetOrdersMapper petOrdersMapper;

    @Autowired
    private PetCartMapper petCartMapper;

    public JSONObject login(String js_code) {
        JSONObject jsonObject = new JSONObject();
        String url = loginUrl + "?grant_type=authorization_code&appid=" + appId + "&secret=" + appSecret + "&js_code=" + js_code;
        //String url = "https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code&appid=wxabded2439d2f2661&secret=edfe22418d74fc2e3e93362738a3eec7&js_code=12323234324";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> stringResponseEntity = restTemplate.getForEntity(url, String.class);
        if (HttpStatus.OK.value() == stringResponseEntity.getStatusCodeValue()) {
            jsonObject = JSON.parseObject(stringResponseEntity.getBody());
            //if (null != jsonObject && Integer.valueOf(0).equals(jsonObject.getInteger("errcode"))) {
            if (null != jsonObject && StringUtils.isNotBlank(jsonObject.getString("openid"))) {
                //成功
                //获取token
                String token = getToken();
                jsonObject.put("token", token);
                String openid = jsonObject.getString("openid");
                redisCache.setCacheObject(openid, jsonObject, 7000, TimeUnit.SECONDS);
                PetCustomer petCustomerByOpenid = customerMapper.selectPetCustomerByOpenid(openid);
                if (ObjectUtils.isEmpty(petCustomerByOpenid)) {
                    //不存在，则生成客户
                    PetCustomer petCustomer = new PetCustomer();
                    petCustomer.setOpenid(openid);
                    customerMapper.insertPetCustomer(petCustomer);
                }
            }
        }
        return jsonObject;
    }

    public String getMobile(String openid, String code) {
        JSONObject cacheObject = redisCache.getCacheObject(openid);
        if (null == cacheObject || StringUtils.isBlank(cacheObject.getString("token"))) {
            return null;
        }
        String url = phoneNumUrl + "?access_token=" + cacheObject.getString("token");

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

        JSONObject body = new JSONObject().fluentPut("code", code);
        HttpEntity<String> entity = new HttpEntity<>(body.toJSONString(), headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, JSONObject.class);

        String phoneNum = null;
        if (HttpStatus.OK.value() == responseEntity.getStatusCodeValue()) {
            JSONObject responseEntityBody = responseEntity.getBody();
            if (null != responseEntityBody && 0 == responseEntityBody.getInteger("errcode")) {
                //成功
                phoneNum = responseEntityBody.getJSONObject("phone_info").getString("phoneNumber");
            }
        }
        return phoneNum;
    }

    public String getToken() {
        String url = tokenUrl + "?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
        //String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxabded2439d2f2661&secret=edfe22418d74fc2e3e93362738a3eec7";
        RestTemplate restTemplate = new RestTemplate();
        JSONObject jsonObject = restTemplate.getForObject(url, JSONObject.class);
        return null != jsonObject ? jsonObject.getString("access_token") : null;
    }

    public int updateCustomer(String openid, String nickName) {
        PetCustomer petCustomer = new PetCustomer();
        petCustomer.setOpenid(openid);
        PetCustomer customerByOpenid = customerMapper.selectPetCustomerByOpenid(openid);
        if (ObjectUtils.isEmpty(customerByOpenid)) {
            return 0;
        }
        customerByOpenid.setNickName(nickName);
        return customerMapper.updatePetCustomer(customerByOpenid);
    }

    public List<SysUser> getMerchantList(String openid) {
        if (verfiyAccesstoken(openid)) {
            return new ArrayList<>();
        }
        return sysUserMapper.selectUserListByOpenid(openid);
    }

    public JSONObject addMerchant(String openid, String merchantCode) {
        if (verfiyAccesstoken(openid)) {
            return new JSONObject().fluentPut("errcode", 1).fluentPut("errmsg", "token过期，请重新登录");
        }
        SysUser sysUser = sysUserMapper.selectUserByMerchantCode(merchantCode);
        if (ObjectUtils.isEmpty(sysUser)) {
            //输入的商户码不正确
            return new JSONObject().fluentPut("errcode", 1).fluentPut("errmsg", "输入的商户码不正确");
        }

        //正确的，则建立关联关系
        PetCustomerUser petCustomerUser = new PetCustomerUser();
        petCustomerUser.setUserId(sysUser.getUserId());
        petCustomerUser.setOpenid(openid);
        int count = petCustomerUserMapper.selectPetCustomerUserByEntity(petCustomerUser);
        if (0 != count) {
            return new JSONObject().fluentPut("errcode", 1).fluentPut("errmsg", "您已经添加该商户，请勿重复添加");
        }
        int i = petCustomerUserMapper.insertPetCustomerUser(petCustomerUser);
        if (1 != i) {
            return new JSONObject().fluentPut("errcode", 1).fluentPut("errmsg", "加入商家失败，请联系管理员！");
        }
        return new JSONObject().fluentPut("errcode", 0).fluentPut("errmsg", "成功");
    }

    public List<String> getCategoryList(String openid) {
        if (verfiyAccesstoken(openid)) {
            return new ArrayList<>();
        }
        return dictDataMapper.selectDictDataStringByType("pet_category");
    }

    public List<String> getBrandList(String openid, Long userId, String category) {
        if (verfiyAccesstoken(openid)) {
            return new ArrayList<>();
        }
        return petProductMapper.selectPetBrandCategoryBrandList(userId, category);
    }

    public List<PetProduct> getProductList(String openid, String brandName,
                                           String category, Long userId) {
        if (verfiyAccesstoken(openid)) {
            return new ArrayList<>();
        }
        PetProduct petProduct = new PetProduct();
        petProduct.setCategory(category);
        petProduct.setBrandName(brandName);
        petProduct.setUserId(userId);
        return petProductMapper.selectPetProductListWx(petProduct);
    }

    public String merchantApply(String openid, String userName, String mobile) {
        if (verfiyAccesstoken(openid)) {
            return "您未登录，请先登录";
        }
        //先判断该手机号是否已经是商户
        SysUser userByMobile = sysUserMapper.selectUserByMobile(mobile);
        if (null != userByMobile && null != userByMobile.getUserId()) {
            return "该手机号已经是商户，请勿重复申请";
        }

        PetApply petApplySelect = new PetApply();
        petApplySelect.setMobile(mobile);
        List<PetApply> petApplyList = applyMapper.selectPetApplyList(petApplySelect);
        if (CollectionUtils.isNotEmpty(petApplyList)) {
            //表示已经申请过
            return "您的申请正在处理中，请耐心等待客服联系您！";
        }

        PetApply apply = new PetApply();
        apply.setUserName(userName);
        apply.setMobile(mobile);
        int i = applyMapper.insertPetApply(apply);
        if (1 == i) {
            return null;
        }
        return "申请商户失败，请联系管理员";
    }

    public JSONArray selectPetCartListWx(String openid, Long userId) {
        if (verfiyAccesstoken(openid)) {
            return new JSONArray();
        }
        List<Map<String, Object>> mapList = petCartMapper.selectPetCartListWx(openid, userId);
        Map<Long, List<Map<String, Object>>> userIdMap = mapList.stream().collect(Collectors.groupingBy(e -> (Long) e.get("userId")));
        JSONArray userList = new JSONArray();
        for (Long userIdItem : userIdMap.keySet()) {
            SysUser sysUser = sysUserMapper.selectUserById(userIdItem);
            JSONObject jsonObject = new JSONObject()
                    .fluentPut("userId", userIdItem)
                    .fluentPut("merchantName", sysUser.getMerchantName())
                    .fluentPut("mobile", sysUser.getMobile())
                    .fluentPut("wechat", sysUser.getWechat())
                    .fluentPut("cartList", userIdMap.get(userIdItem));
            userList.add(jsonObject);
        }
        return userList;
    }

    public int insertPetCart(PetCart petCart) {
        if (verfiyAccesstoken(petCart.getOpenid())) {
            return 0;
        }
        PetCart petCartSelect = petCartMapper.selectPetCartWx(petCart);
        if (ObjectUtils.isEmpty(petCartSelect)) {
            petCart.setCreateTime(DateUtils.getNowDate());
            petCart.setQuantity(1L);
            return petCartMapper.insertPetCart(petCart);
        } else {
            petCart.setId(petCartSelect.getId());
            petCart.setQuantity(petCartSelect.getQuantity() + 1);
            return petCartMapper.updatePetCart(petCart);
        }
    }

    public int deletePetCartById(Long id) {
        return petCartMapper.deletePetCartById(id);
    }

    public int insertPetOrders(String openid, String cartIds) {
        if (verfiyAccesstoken(openid)) {
            return 0;
        }
        PetOrders petOrders = new PetOrders();
        petOrders.setCartIds(cartIds);
        petOrders.setOpenid(openid);
        List<PetOrders> petOrdersList = petOrdersMapper.selectPetOrdersList(petOrders);
        if (CollectionUtils.isNotEmpty(petOrdersList)) {
            return 1;
        }
        return petOrdersMapper.insertPetOrders(petOrders);
    }

    private boolean verfiyAccesstoken(String openid) {
        JSONObject cacheObject = redisCache.getCacheObject(openid);
        return null == cacheObject || StringUtils.isBlank(cacheObject.getString("token"));
    }
}
